package config

import (
	"fmt"
	"os"
	"path/filepath"
	"strings"

	"gopkg.in/yaml.v3"
)

// ConfigLoader 配置加载器
type ConfigLoader struct {
	configPath string
	config     *Config
}

// NewConfigLoader 创建配置加载器
func NewConfigLoader(configPath string) *ConfigLoader {
	return &ConfigLoader{
		configPath: configPath,
	}
}

// Load 加载配置文件
func (cl *ConfigLoader) Load() (*Config, error) {
	// 如果配置文件路径为空，尝试查找默认配置文件
	if cl.configPath == "" {
		cl.configPath = cl.findDefaultConfig()
	}

	config, err := LoadConfig(cl.configPath)
	if err != nil {
		return nil, err
	}

	cl.config = config
	return config, nil
}

// Reload 重新加载配置文件
func (cl *ConfigLoader) Reload() (*Config, error) {
	return cl.Load()
}

// GetConfig 获取当前配置
func (cl *ConfigLoader) GetConfig() *Config {
	return cl.config
}

// FindDefaultConfig 查找默认配置文件（公共方法）
func FindDefaultConfig() string {
	loader := &ConfigLoader{}
	return loader.findDefaultConfig()
}

// findDefaultConfig 查找默认配置文件
func (cl *ConfigLoader) findDefaultConfig() string {
	// 按优先级查找配置文件
	configPaths := []string{
		"./config.yaml",
		"./configs/config.yaml",
		"./config.yml",
		"./configs/config.yml",
		"/etc/health-check/config.yaml",
		"/etc/health-check/config.yml",
		"~/.health-check/config.yaml",
		"~/.health-check/config.yml",
	}

	for _, path := range configPaths {
		// 处理 ~ 路径
		if strings.HasPrefix(path, "~/") {
			homeDir, err := os.UserHomeDir()
			if err != nil {
				continue
			}
			path = filepath.Join(homeDir, path[2:])
		}

		if _, err := os.Stat(path); err == nil {
			return path
		}
	}

	// 如果找不到配置文件，返回默认路径
	return "./config.yaml"
}

// ValidateConfigPath 验证配置文件路径
func ValidateConfigPath(configPath string) error {
	if configPath == "" {
		return fmt.Errorf("配置文件路径不能为空")
	}

	// 检查文件是否存在
	if _, err := os.Stat(configPath); os.IsNotExist(err) {
		return fmt.Errorf("配置文件不存在: %s", configPath)
	}

	// 检查文件扩展名
	ext := strings.ToLower(filepath.Ext(configPath))
	if ext != ".yaml" && ext != ".yml" {
		return fmt.Errorf("配置文件必须是 .yaml 或 .yml 格式")
	}

	return nil
}

// CreateDefaultConfig 创建默认配置文件
func CreateDefaultConfig(configPath string) error {
	// 创建默认配置
	config := &Config{
		Global: GlobalConfig{
			CheckInterval: 30,
			Timeout:       10,
			RetryCount:    3,
			RetryDelay:    5,
			ServerID:      "",
		},
		Processes: []ProcessConfig{
			{
				Name:        "nginx",
				Enabled:     true,
				AutoRestart: true,
				RestartCmd:  "systemctl restart nginx",
			},
		},
		Logging: LoggingConfig{
			Level:      "info",
			Format:     "text",
			Output:     "stdout",
			MaxSize:    100,
			MaxBackups: 3,
			MaxAge:     7,
		},
		Notify: NotificationConfig{
			Enabled: false,
		},
	}

	return SaveConfig(config, configPath)
}

// GetConfigDir 获取配置目录
func GetConfigDir() (string, error) {
	homeDir, err := os.UserHomeDir()
	if err != nil {
		return "", fmt.Errorf("获取用户主目录失败: %v", err)
	}

	configDir := filepath.Join(homeDir, ".health-check")

	// 创建配置目录
	if err := os.MkdirAll(configDir, 0755); err != nil {
		return "", fmt.Errorf("创建配置目录失败: %v", err)
	}

	return configDir, nil
}

// Save 保存配置到文件
func (cl *ConfigLoader) Save(cfg *Config) error {
	data, err := yaml.Marshal(cfg)
	if err != nil {
		return fmt.Errorf("序列化配置失败: %v", err)
	}

	if err := os.WriteFile(cl.configPath, data, 0644); err != nil {
		return fmt.Errorf("写入配置文件失败: %v", err)
	}

	return nil
}

// LoadProcessConfigs 加载进程配置文件目录中的所有配置文件
func LoadProcessConfigs(processesDir string) ([]ProcessConfig, error) {
	var allProcesses []ProcessConfig

	// 检查目录是否存在
	if _, err := os.Stat(processesDir); os.IsNotExist(err) {
		// 目录不存在，返回空列表
		return allProcesses, nil
	}

	// 读取目录中的所有 .yaml 和 .yml 文件
	files, err := filepath.Glob(filepath.Join(processesDir, "*.yaml"))
	if err != nil {
		return nil, fmt.Errorf("读取进程配置文件目录失败: %v", err)
	}

	ymlFiles, err := filepath.Glob(filepath.Join(processesDir, "*.yml"))
	if err != nil {
		return nil, fmt.Errorf("读取进程配置文件目录失败: %v", err)
	}

	files = append(files, ymlFiles...)

	// 加载每个文件
	for _, file := range files {
		processConfig, err := loadSingleProcessConfig(file)
		if err != nil {
			fmt.Printf("[CONFIG] 加载进程配置文件失败 %s: %v\n", file, err)
			continue // 跳过错误的文件，继续加载其他文件
		}
		allProcesses = append(allProcesses, processConfig)
	}

	return allProcesses, nil
}

// loadSingleProcessConfig 加载单个进程配置文件
func loadSingleProcessConfig(filePath string) (ProcessConfig, error) {
	data, err := os.ReadFile(filePath)
	if err != nil {
		return ProcessConfig{}, fmt.Errorf("读取文件失败: %v", err)
	}

	// 跳过空文件
	if len(data) == 0 {
		return ProcessConfig{}, fmt.Errorf("文件为空")
	}

	var processFile ProcessConfigFile
	if err := yaml.Unmarshal(data, &processFile); err != nil {
		return ProcessConfig{}, fmt.Errorf("解析配置文件失败: %v", err)
	}

	// 检查是否成功解析出进程配置
	if processFile.Process.Name == "" {
		return ProcessConfig{}, fmt.Errorf("进程名称为空，请检查文件格式是否正确（应使用 'process:' 作为顶级键）")
	}

	// 验证单个进程配置
	if err := validateSingleProcessConfig(&processFile.Process); err != nil {
		return ProcessConfig{}, fmt.Errorf("配置验证失败: %v", err)
	}

	return processFile.Process, nil
}

// SaveProcessConfig 保存单个进程配置到文件
func SaveProcessConfig(process ProcessConfig, processesDir string) error {
	// 确保目录存在
	if err := os.MkdirAll(processesDir, 0755); err != nil {
		return fmt.Errorf("创建进程配置目录失败: %v", err)
	}

	// 生成文件名（使用进程名称）
	fileName := fmt.Sprintf("%s.yaml", process.Name)
	filePath := filepath.Join(processesDir, fileName)

	// 创建配置结构
	processFile := ProcessConfigFile{
		Process: process,
	}

	data, err := yaml.Marshal(processFile)
	if err != nil {
		return fmt.Errorf("序列化配置失败: %v", err)
	}

	if err := os.WriteFile(filePath, data, 0644); err != nil {
		return fmt.Errorf("写入配置文件失败: %v", err)
	}

	return nil
}

// DeleteProcessConfig 删除进程配置文件
func DeleteProcessConfig(processName, processesDir string) error {
	fileName := fmt.Sprintf("%s.yaml", processName)
	filePath := filepath.Join(processesDir, fileName)

	if err := os.Remove(filePath); err != nil {
		if os.IsNotExist(err) {
			return fmt.Errorf("进程配置文件不存在: %s", processName)
		}
		return fmt.Errorf("删除配置文件失败: %v", err)
	}

	return nil
}
